#ifndef SMTPBASE_H
#define SMTPBASE_H

#pragma once
#include "AbstractSmtp.h"

namespace smtp {

    class SmtpBase
        : public AbstractSmtp {
    public:
        SmtpBase();
        virtual ~SmtpBase() {};

    public:
        virtual bool login(std::string username, std::string password) override;
        virtual bool mail(const AbstractMail* mail) override;
        virtual bool quit() override;

    protected:
        virtual void        send(const std::string& msg) = 0;
        virtual std::string get_response()               = 0;

    protected:
        template <typename Stream>
        void send(Stream& stream, const std::string& msg) {
            boost::asio::write(stream, boost::asio::buffer(msg));
        };

        template <typename Stream>
        std::string get_response(Stream& stream) {
            boost::asio::streambuf buffer;
            for (;;) {
                std::string msg;
                boost::asio::read_until(stream, buffer, "\r\n");
                std::istream in(&buffer);
                std::getline(in, msg);
                return msg;
            }
        };

        void send_file(std::string file_path);

        const std::string base64_encode(const char* bytes_to_encode, unsigned int in_len) const;

        const std::string get_filename(std::string& file_path) const;

    private:
        const char* base64_chars = "ABCDEFGHIJK\
LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    };
}  // namespace smtp

#endif